using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using NWrapper.Entities;

namespace NWrapper
{
    /// <summary>
    /// Defines the interface for a repository which supports Linq methods.
    /// </summary>
	public interface ILinqRepository
	{
		/// <summary>
		/// Finds the instance of a given type that matches the given criteria.
		/// If more than one result is found, an exception should be thrown.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <param name="criteria">The search criteria.</param>
		/// <returns>An object instance, or null if not found.</returns>
		T FindOne<T>(Expression<Func<T, bool>> criteria);

		/// <summary>
		/// Finds the first instance of a given type that matches the given criteria.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <param name="criteria">The search criteria.</param>
		/// <returns>An object instance, or null if not found.</returns>
		T FindFirst<T>(Expression<Func<T, bool>> criteria);

		/// <summary>
		/// Finds all instances of a given type that matches the given criteria.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <param name="criteria">The search criteria.</param>
		/// <returns>An collection of object instance. If no objects are found, an empty collection is returned.</returns>
		IList<T> FindAll<T>(Expression<Func<T, bool>> criteria);

		/// <summary>
		/// Deletes instances of a given type that match the given criteria.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <param name="criteria">The search criteria.</param>
		void Delete<T>(Expression<Func<T, bool>> criteria);

		/// <summary>
		/// Gets the total number of records of a given type that match the given criteria.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <param name="criteria">The search criteria.</param>
		/// <returns>The total number of records.</returns>
		int Count<T>(Expression<Func<T, bool>> criteria);
	}
}
